const fs = require('fs-extra');
const path = require('path');
const { default: OpenAI } = require('openai');
const {
    AI_API_KEY,
    AI_BASE_API_URL,
    OSS_REGION,
    OSS_ACCESS_KEY_ID,
    OSS_ACCESS_KEY_SECRET,
    OSS_BUCKET_NAME,
} = require('./config');
const OSS = require('ali-oss');

/** @type {OpenAI} */
let aiInstance;
async function getOpenAI() {
    if (aiInstance) {
        return aiInstance;
    }
    console.log('初始化AI大模型API实例');
    const OpenAI = (await import('openai')).default;
    console.log('初始化成功');
    const openAI = new OpenAI({
        apiKey: AI_API_KEY,
        baseURL: AI_BASE_API_URL,
    });
    aiInstance = openAI;
    return aiInstance;
}

exports.getOpenAI = getOpenAI;

async function uploadPDF(pdfFilePath) {
    console.log('上传PDF到大模型');
    console.log('PDF地址：' + pdfFilePath);
    const openAI = await getOpenAI();
    const fileObject = await openAI.files.create({
        file: fs.createReadStream(pdfFilePath),
        purpose: 'file-extract',
    });
    console.log('PDF上传结束，大模型文件ID：' + fileObject.id);
    return fileObject.id;
}

const store = new OSS({
    region: OSS_REGION,
    accessKeyId: OSS_ACCESS_KEY_ID,
    accessKeySecret: OSS_ACCESS_KEY_SECRET,
    bucket: OSS_BUCKET_NAME,
});
async function uploadToOss(filePath) {
    const pathParts = filePath.split(path.sep);
    const len = pathParts.length;
    const fileName = encodeURIComponent(pathParts[len - 1]);
    const pdfHash = encodeURIComponent(pathParts[len - 2]);
    const zipHash = encodeURIComponent(pathParts[len - 3]);
    const userId = encodeURIComponent(pathParts[len - 4]);
    const uploadPath = [userId, zipHash, pdfHash, fileName].join('/');
    console.log('上传文件到阿里云OSS: ' + uploadPath);
    console.log('本地文件地址：' + filePath);
    const res = await store.put(uploadPath, fs.readFileSync(filePath));
    const fileId = res?.url;
    if (fileId) {
        return fileId;
    }
    console.log(res);
    throw new Error('上传文件到oss失败：' + filePath);
}

exports.uploadPDF = uploadPDF;
exports.uploadToOss = uploadToOss;
exports.getFileId = function (filePath) {
    const ext = path.extname(filePath);
    if (ext === '.pdf') {
        return uploadPDF(filePath);
    } else {
        return uploadToOss(filePath);
    }
};

exports.streamCompletion = async function(res, completion) {
    res.writeHead(200, {
        'content-type': 'text/plain; charset=utf-8',
    });
    for await (const chunk of completion) {
        const [choice] = chunk.choices;
        const { content } = choice.delta;
        res.write(content);
    }
    res.end();
}